/**
 *  @author Morozan Ion
 *  
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.dddforandroid.c2dm;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

import com.dddforandroid.util.Util;
/**
 * 
 * Handle the process of sending an c2dm message to an Android device.  
 *
 */
public class MessageUtil {
	@SuppressWarnings("unused")
	private final static String AUTH = "authentication";

	private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth";

	public static final String PARAM_REGISTRATION_ID = "registration_id";

	public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle";

	public static final String PARAM_COLLAPSE_KEY = "collapse_key";

	public static final String C2DM_SEND_ENDPOINT = "https://android.clients.google.com/c2dm/send";

	private static final String UTF8 = "UTF-8";

	public static int sendMessage(String auth_token, String registrationId,
			String message) throws IOException {

		/** prepare the message to send */
		StringBuilder postDataBuilder = new StringBuilder();
		postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
				.append(registrationId);
		postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
				.append("0");
		postDataBuilder.append("&").append("data.payload").append("=")
				.append(URLEncoder.encode(message, UTF8));

		byte[] postData = postDataBuilder.toString().getBytes(UTF8);

		/** Hit the dm URL. */
		URL url = new URL(C2DM_SEND_ENDPOINT);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded;charset=UTF-8");
		conn.setRequestProperty("Content-Length",
				Integer.toString(postData.length));
		conn.setRequestProperty("Authorization", "GoogleLogin auth="
				+ auth_token);

		OutputStream out = conn.getOutputStream();
		out.write(postData);
		out.close();

		int responseCode = conn.getResponseCode();

		/**
		 * The token is too old. This happens if the password is changed or
		 * token expires. Either admin is updating the token, or
		 * Update-Client-Auth was received by another server, and next retry
		 * will get the good one from database.
		 */
		if (responseCode == HttpServletResponse.SC_UNAUTHORIZED
				|| responseCode == HttpServletResponse.SC_FORBIDDEN) {
			AuthenticationUtil.getTokenFromServer(Util.USER, Util.PASSWORD);

			/** and send message again */
			sendMessage(auth_token, registrationId, message);
		}

		/** Check for updated token header */
		String updatedAuthToken = conn.getHeaderField(UPDATE_CLIENT_AUTH);
		if (updatedAuthToken != null && !auth_token.equals(updatedAuthToken)) {
			Util.updateToken(updatedAuthToken);
		}

		return responseCode;
	}

}